/*
 * Copyright (c) 2011 Ball State University
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * NOTE:
 * Derivative work based on the Google IO 2011 Schedule app released for open source
 * http://code.google.com/p/iosched/
 */

package edu.bsu.android.gtv.apps.bconnected.util;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

import edu.bsu.android.gtv.apps.bconnected.data.DBAdapter;
import edu.bsu.android.gtv.apps.bconnected.objects.Person;

import android.app.Activity;
import android.content.Context;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.os.AsyncTask;
import android.preference.PreferenceManager;
import android.util.Log;

/**
 * LoginHelper used to determine whether a user has authenticated and checks the local database credentials 
 * @author Kyle Parker, University Computing Services
 *
 */
public class LoginHelper {
	/**
	 * Determines whether a student has successfully logged into the application
	 * @param context
	 * @return true|false
	 */
    public static boolean hasLoggedIn(final Context context) {
        SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context);
        return sp.getBoolean("logged_in", false);
    }
    
    // TODO: Add this as a column to the SQLite "security" table for the app.  This was not added originally because students were already 
    // using the app and adding the column would have caused a drop/re-create of the table, thereby losing their saved data.  Instead a
    // shared preference was used to determine if the account was a real student or the demo account.
    /**
     * Determine whether the user is using the demo account for the application. 
     * @param context
     * @return true|false
     */
    public static boolean isDemoAccount(final Context context) {
        SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context);
        return sp.getBoolean("demo_account", false);
    }

    /**
     * Sets the login shared preference
     * @param context
     * @param auth
     */
    public static void setLogin(final Context context, final boolean auth) {
        new AsyncTask<Void, Void, Void>() {
            @Override
            protected Void doInBackground(Void... voids) {
                SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context);
                sp.edit().putBoolean("logged_in", auth).commit();
                return null;
            }
        }.execute();
    }

    /**
     * Set the demo account shared preference
     * @param context
     * @param account
     */
    public static void setDemoAccount(final Context context, final boolean account) {
        new AsyncTask<Void, Void, Void>() {
            @Override
            protected Void doInBackground(Void... voids) {
                SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context);
                sp.edit().putBoolean("demo_account", account).commit();
                return null;
            }
        }.execute();
    }
    
    /**
     * Check the credentials for the person logged in - the expiration date cannot be greater than today's date
     * If the credentials are not validated, then the user will be asked to log into the application again.
     * The login guid is a uniqueidentifier data type, created on the SQL Server backend when a student logs in.  This guid is 
     * saved to the Login table and used to validate/authenticate that the calls the service handler are permitted. 
     * This was done in an attempt to keep someone from hacking the querystring and retrieving another student's data. 
     * If the combination of BSU ID and Login guid (both of which are encrypted) do not match what is in the SQL Server 
     * database, then an error attribute is returned through the XML and no other data is returned (i.e., classmate lists,
     * organizations, housing info, etc).
     * @param data
     * @param activity
     * @return person
     */
    private static Person checkCredentials(Cursor data, Activity activity) { 
    	Person person = null; 
		
        // If there is data in the cursor, determine the expiration date
        if (data.getCount() > 0) {    
	    	DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 
	    	
        	// Retrieve the values from the cursor
            Date expirationDate = Calendar.getInstance().getTime();
            
			try  {
				expirationDate = df.parse(data.getString(data.getColumnIndex(DBAdapter.KEY_EXPIRATION_DATE)));
			} catch (ParseException e)  {
				Log.e("checkCredentials", e.getMessage());
			} 
			
            String bsuID = data.getString(data.getColumnIndex(DBAdapter.KEY_BSUID));
            String firstName = data.getString(data.getColumnIndex(DBAdapter.KEY_FIRST_NAME));
            String loginGuid = data.getString(data.getColumnIndex(DBAdapter.KEY_UNIQUE_ID));
            Date todayDate = Calendar.getInstance().getTime(); 
            
            // Determine if the expiration date is valid
            if (expirationDate.before(todayDate)) {
            	// If the expiration date is not valid, set the login preference to false so the "login" option appears in the menu
            	LoginHelper.setLogin(activity, false);
            } else {
            	person = new Person();
            	
            	person.setBSUID(bsuID);
            	person.setFirstName(firstName);
            	person.setLoginGuid(loginGuid);
            }
        } else {
        	// If the expiration date is not valid, set the login preference to false so the "login" option appears in the menu
        	LoginHelper.setLogin(activity, false);
        }
    	
        return person;
	}
    
    /**
     * Check the security credentials and make sure the user has logged in and the expiration date has not expired
     * @param activity
     * @return person
     */
    public static Person checkLogin(Activity activity) {
        DBAdapter db = new DBAdapter(activity);
        db.open();
	    
	    // Retrieve the most recent activity for the user
        Cursor data = db.getSecurityMostRecent();
        
        activity.startManagingCursor(data);         
        Person person = LoginHelper.checkCredentials(data, activity); 
        activity.stopManagingCursor(data);
        //data.close();
        db.close(); 
        
        return person;
    }
}
